﻿using System;
using System.Collections.Generic;
using System.Collections;

namespace Fennec
{
    public abstract class Civilisation
    {
        public bool directeur_vivant { get; protected set; }
        public Hashtable unités { get; protected set; }
        public List<Ville> villes { get; protected set; }
        public int nombreVilles { get; protected set; }
        public ECivilisationNom nom { get; protected set; }

        protected Civilisation(ECivilisationNom n)
        {
            nom = n;

            unités = new Hashtable();
            villes = new List<Ville>();

            directeur_vivant = false;
        }

        public void finirTour()
        {
            foreach (Ville ville in villes)
            {
                ville.finirTour();
            }
            foreach (Unité unité in unités)
            {
                unité.finirTour();
            }
        }

        public bool estVivante()
        {
            return this.villes.Count != 0;
        }

        public bool peutVoir(System.Drawing.Point position)
        {
            foreach (Ville ville in villes)
            {
                if (ville.peutVoirCase(position))
                {
                    return true;
                }
            }
            foreach (Unité unité in unités)
            {
                if (unité.peutVoir(position))
                {
                    return true;
                }
            }
            return false;
        }

        /* unités */

        // fabrique abstraite
        public abstract UnitéDirecteur creerDirecteur(System.Drawing.Point pos);
        public abstract UnitéEtudiant creerEtudiant(System.Drawing.Point pos);
        public abstract UnitéEnseignant creerEnseignant(System.Drawing.Point pos);

        public void ajouterDirecteur(System.Drawing.Point position)
        {
            if (!directeur_vivant)
            {
                UnitéDirecteur u = this.creerDirecteur(position);
                unités.Add(unités.Count, u);
                directeur_vivant = true;
            }
            else
            {
                throw new ActionImpossibleException("Une civilisation ayant un directeur vivant ne peut en créer d'autre");
            }
        }

        public void ajouterEnseignant(System.Drawing.Point position)
        {
            UnitéEnseignant u = this.creerEnseignant(position);
            unités.Add(unités.Count, u);
        }

        public void ajouterEtudiant(System.Drawing.Point position)
        {
            UnitéEtudiant u = this.creerEtudiant(position);
            unités.Add(unités.Count, u);
        }

        public Unité getUnité(System.Drawing.Point position, int id)
        {
            Hashtable hashtable = getUnités(position);
            return (Unité)hashtable[id];
        }

        public Hashtable getUnités(System.Drawing.Point position)
        {
            Hashtable hashtable = new Hashtable(unités);

            foreach (Unité unité in unités)
            {
                if (!unité.position.Equals(position))
                {
                    hashtable.Remove(unité);
                }
            }

            return hashtable;
        }

        public void supprimerUnité(System.Drawing.Point position, int id)
        {
            unités.Remove(id);
        }

        /* villes */

        // les vérifications quant à la disponibilité de cette case
        // doivent être réalisées en amont de l'appel à cette méthode
        public void ajouterVille(Carte carte, System.Drawing.Point position)
        {
            Ville ville = new Ville(carte, position);
            villes.Add(ville);
        }

        public Ville getVille(System.Drawing.Point position)
        {
            foreach (Ville ville in villes)
            {
                if (ville.position.Equals(position))
                {
                    return (Ville)ville;
                }
            }
            return null;
        }

        public bool possedeVille(System.Drawing.Point position)
        {
            return this.getVille(position) != null;
        }

        public void supprimerVille(System.Drawing.Point position)
        {
            Ville v = this.getVille(position);
            if (position != null)
            {
                villes.Remove(v);
            }
            else
            {
                throw new ActionImpossibleException("Cette civilisation ne possède aucune ville à la position ("
                    + position.X + "," + position.Y + ")");
            }
        }
    }
}